package py.com.erpone.session.dm;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;

import org.primefaces.model.DualListModel;

import py.com.erpone.entity.dm.Rol;
import py.com.erpone.entity.dm.Usuario;
import py.com.erpone.session.dm.list.RolList;
import py.com.erpone.session.dm.list.UsuarioList;

@Stateful
@Named
@LocalBean
@ConversationScoped
public class UsuarioBean {

	@PersistenceContext(type = PersistenceContextType.EXTENDED)
	private EntityManager em;

	@Inject
	private Conversation conversation;

	@Inject
	private UsuarioList usuarioList;

	@Inject
	private RolList rolList;

	private DualListModel<Rol> dualListRol;

	private String nombreUsuario;

	private Usuario usuario;

	@Inject
	private RolBean rolBean;

	@Inject
	private TareaBean tareaBean;

	@PostConstruct
	public void postConstruct() {
		List<Rol> source = rolList.findAll();// Agrego las tareas al source.
		List<Rol> target = new ArrayList<Rol>();
		this.dualListRol = new DualListModel<Rol>(source, target);
	}

	public UsuarioBean() {

	}

	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}

	public void iniciar() {
		if (conversation.isTransient())
			conversation.begin();
		usuario = new Usuario();
		rolBean.iniciar();// Iniciamos la conversacion para los roles.
		// tareaBean.iniciar();//Iniciamos la conversacion para las tareas
		// return "/dm/usuario.xhtml";//Redirigimos a la pagina que contiene el
		// form para un nuevo usuario y sus roles.
	}

	public void iniciar(Usuario usuario) {
		if (conversation.isTransient())
			conversation.begin();

		this.usuario = usuarioList.findByNombreUsuario(usuario
				.getNombreUsuario());
		nombreUsuario = usuario.getNombreUsuario();
		
		for(Rol r: this.usuario.getRol()){
			this.dualListRol.getTarget().add(r);
			this.dualListRol.getSource().remove(r);
			
		}
		
		// return "/dm/usuario.xhtml";
	}

	public void guardar() {
		usuario.setRol((List<Rol>) dualListRol.getTarget());

		if (getUsuarioNombre() == null) {
			encriptarPassword();
			usuario.setNombreUsuario(getNombreUsuario());
			em.persist(usuario);
		} else {
			String pass = usuarioList.getPasswordByNombreUsuario(usuario);
			if (nombreUsuario != null) {
				usuario.setPassword(pass);
			}
			if (!usuario.getPassword().equals("")
					&& !pass.equals(usuario.getPassword())) {
				encriptarPassword();
			}
			if (!nombreUsuario.equals(usuario.getNombreUsuario())) {
				Usuario newUser = new Usuario(nombreUsuario, pass);
				newUser.setRol(usuario.getRol());
				em.persist(newUser);

				em.remove(em.merge(usuario));
			} else
				em.merge(usuario);
		}
		if (!conversation.isTransient())
			conversation.end();

	}

	public void eliminar(Usuario usuario) {
		em.remove(em.merge(usuario));
		if (!conversation.isTransient())
			conversation.end();

	}

	public void cancelar() {
		if (!conversation.isTransient())
			conversation.end();
	}

	public DualListModel<Rol> getDualListRol() {
		return dualListRol;
	}

	public void setDualListRol(DualListModel<Rol> rol) {
		this.dualListRol = rol;
	}

	private void encriptarPassword() {
		MessageDigest sha;
		try {
			sha = MessageDigest.getInstance("SHA-512");
			byte[] hashPassword = sha.digest(usuario.getPassword().getBytes());
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < hashPassword.length; i++) {
				sb.append(Integer
						.toString((hashPassword[i] & 0xff) + 0x100, 16)
						.substring(1));
			}
			usuario.setPassword(sb.toString());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}

	private String getUsuarioNombre() {
		try {
			String usuarioNombre = (String) em
					.createNamedQuery("usuario.nombreUsuario")
					.setParameter("nombreUsuario", usuario.getNombreUsuario())
					.getSingleResult();
			return usuarioNombre;
		} catch (NoResultException e) {
			return null;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public String getNombreUsuario() {
		return nombreUsuario;
	}

	public void setNombreUsuario(String nombreUsuario) {
		this.nombreUsuario = nombreUsuario;
	}

}
